package cn.lili.modules.order.order.entity.dto;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.DateUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.enums.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.util.CollectionUtils;

import java.io.Serial;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 订单查询参数
 *
 * @author Chopper
 * @since 2020/11/17 4:33 下午
 */
@EqualsAndHashCode(callSuper = true)
@Data
public class OrderSearchParams extends PageVO {

    @Serial
    private static final long serialVersionUID = -6380573339089959194L;

    @ApiModelProperty(value = "商品名称")
    private String goodsName;

    @ApiModelProperty(value = "订单编号")
    private String orderSn;

    @ApiModelProperty(value = "页面标签", example = "ALL:全部," + "WAIT_PAY:待付款," + "WAIT_ROG:待收货," + "CANCELLED:已取消," + "COMPLETE:已完成")
    private String tag;

    @ApiModelProperty(value = "商家ID")
    private String storeId;

    @ApiModelProperty(value = "是否为采购单")
    private boolean purchase;

    @ApiModelProperty(value = "供应商ID")
    private String supplierId;

    @ApiModelProperty(value = "购买人ID")
    private String buyerId;

    @ApiModelProperty(value = "买家昵称")
    private String nickname;

    @ApiModelProperty(value = "收货人")
    private String shipName;

    @ApiModelProperty(value = "订单状态")
    private String orderStatus;

    @ApiModelProperty(value = "付款状态")
    private String payStatus;

    @ApiModelProperty(value = "关键字 商品名称/买家名称/店铺名称")
    private String keywords;

    @ApiModelProperty(value = "付款方式")
    private String paymentType;

    /**
     * @see OrderTypeEnum
     * @see cn.lili.modules.order.order.entity.enums.OrderPromotionTypeEnum
     */
    @ApiModelProperty(value = "订单类型", allowableValues = "NORMAL,VIRTUAL,GIFT,PINTUAN,POINT,PURCHASE,BE_IN_PLACE_OF")
    private String orderType;

    @ApiModelProperty(value = "支付方式")
    private String paymentMethod;

    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @ApiModelProperty(value = "支付时间")
    private Date paymentTime;

    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @ApiModelProperty(value = "下单开始时间")
    private Date startDate;

    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @ApiModelProperty(value = "小于等于的开始时间")
    private Date leCreateTime;

    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @ApiModelProperty(value = "小于等于的订单发货时间")
    private Date leLogisticsTime;

    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @ApiModelProperty(value = "小于等于的完成时间")
    private Date leCompleteTime;

    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @ApiModelProperty(value = "下单结束时间")
    private Date endDate;

    @ApiModelProperty(value = "订单来源")
    private String clientType;

    /**
     * @see CommentStatusEnum
     */
    @ApiModelProperty(value = "评论状态:未评论(UNFINISHED),待追评(WAIT_CHASE),评论完成(FINISHED)，")
    private String commentStatus;

    @ApiModelProperty(value = "是否为其他订单下的订单，如果是则为依赖订单的sn，否则为空")
    private String parentOrderSn;

    @ApiModelProperty(value = "是否为某订单类型的订单，如果是则为订单类型的id，否则为空")
    private String promotionId;

    /**
     * @see OrderItemAfterSaleStatusEnum
     */
    @ApiModelProperty(value = "售后状态")
    private String afterSaleStatus;

    @ApiModelProperty(value = "分销员")
    private String distributionId;

    /**
     * @see OrderComplaintStatusEnum
     */
    @ApiModelProperty(value = "投诉状态")
    private String complainStatus;

    /**
     * @see OrderPromotionTypeEnum
     */
    @ApiModelProperty(value = "订单促销类型")
    private String orderPromotionType;

    @ApiModelProperty(value = "总价格,可以为范围，如10_1000")
    private String flowPrice;

    @ApiModelProperty(value = "是否为代理商品订单")
    private Boolean isProxy;

    @ApiModelProperty(value = "城市分站ID")
    private String urbanId;

    /**
     * 盲盒ID
     */
    private String mhId;
    /**
     * 盲盒编号
     */
    private String mhName;
    /**
     * 盲盒订单
     */
    private Boolean mhOrder;

    /**
     * 礼包类型id
     */
    private String packId;

    /**
     * 是否免税订单异常订单
     */
    private Boolean isErrorFree;

    /**
     * 是否免税需要同步的订单
     */
    private Boolean syncOrder;

    /**
     * 交易流水号
     */
    private String outTradeNo;

    /**
     * 导出参数校验
     */
    public void checkoutExportParams() {
        if (this.startDate == null || this.endDate == null) {
            throw new ServiceException(ResultCode.PARAMS_ERROR, "导出订单必须选择时间范围");
        }
        if (this.startDate.after(this.endDate)) {
            throw new ServiceException(ResultCode.PARAMS_ERROR, "导出订单开始时间不能大于结束时间");
        }
        //最多导出180天数据
        if ((this.startDate.getTime() + 180L * 24 * 60 * 60 * 1000) < this.endDate.getTime()) {
            throw new ServiceException(ResultCode.PARAMS_ERROR, "导出信息周期最多180天");
        }
    }


    public <T> QueryWrapper<T> queryWrapper() {
        QueryWrapper<T> wrapper = new QueryWrapper<>();

        //关键字查询
        if (CharSequenceUtil.isNotEmpty(keywords)) {
            wrapper.like("o.sn", keywords).or().like("oi.goods_name", keywords);
        }

        AuthUser currentUser = UserContext.getCurrentUser();
        if (currentUser != null && (mhOrder == null || !mhOrder)) {
            switch (currentUser.getScene()) {
                case MEMBER -> wrapper.eq("o.buyer_id", currentUser.getId());
                case STORE -> {
                    //采购订单，则查询购买人ID，否则查询店铺ID
                    if (purchase) {
                        wrapper.eq("o.buyer_id", currentUser.getExtendId());
                    } else {
                        wrapper.eq("o.store_id", currentUser.getExtendId());
                    }
                }
                case MANAGER -> {
                    if (CharSequenceUtil.isNotEmpty(storeId)) {
                        wrapper.eq("o.store_id", storeId);
                    }
                    if (CharSequenceUtil.isNotEmpty(buyerId)) {
                        wrapper.eq("o.buyer_id", buyerId);
                    }
                }
                case SUPPLIER -> {
                    if (isProxy != null && isProxy) {
                        wrapper.eq("o.supplier_id", currentUser.getExtendId());
                    } else {
                        wrapper.eq("o.store_id", currentUser.getExtendId());
                    }
                }
                case URBAN_SUBSTATION -> {
                    if (isProxy != null && isProxy) {
                        wrapper.eq("urban_id_by_supplier", UserContext.getCurrentUser().getId());
                    }else {
                        wrapper.like("o.urban_id_by_address", UserContext.getCurrentUser().getId())
                                .or().eq("o.urban_id_by_supplier", UserContext.getCurrentUser().getId());
                    }
                }
                default -> {}
            }
        }


        //按照买家查询
        wrapper.like(CharSequenceUtil.isNotEmpty(buyerId), "o.buyer_id", buyerId);

        //按订单编号查询
//        wrapper.like(CharSequenceUtil.isNotEmpty(orderSn), "o.sn", orderSn);
        if (CharSequenceUtil.isNotEmpty(orderSn)) {
            wrapper.and(q -> q.like("o.sn", orderSn).or().eq("oi.sn",orderSn));
        }

        //按时间查询
        wrapper.ge(startDate != null, "o.create_time", startDate);

        wrapper.le(endDate != null, "o.create_time", DateUtil.endOfDate(endDate));

        wrapper.le(leCreateTime != null, "o.create_time", leCreateTime);

        wrapper.le(leLogisticsTime != null, "o.logistics_time", leLogisticsTime);

        wrapper.le(leCompleteTime != null, "o.complete_time", leCompleteTime);
        //按购买人用户名
        wrapper.like(CharSequenceUtil.isNotEmpty(nickname), "o.nickname", nickname);

        //按订单类型
        wrapper.eq(CharSequenceUtil.isNotEmpty(orderType), "o.order_type", orderType);

        //物流查询
        wrapper.like(CharSequenceUtil.isNotEmpty(shipName), "o.consignee_name", shipName);

        //按商品名称查询
        wrapper.like(CharSequenceUtil.isNotEmpty(goodsName), "oi.goods_name", goodsName);

        //付款方式
        wrapper.like(CharSequenceUtil.isNotEmpty(paymentType), "o.payment_type", paymentType);

        //按支付方式
        wrapper.eq(CharSequenceUtil.isNotEmpty(paymentMethod), "o.payment_method", paymentMethod);

        //订单状态
        wrapper.eq(CharSequenceUtil.isNotEmpty(orderStatus), "o.order_status", orderStatus);

        //付款状态
        wrapper.eq(CharSequenceUtil.isNotEmpty(payStatus), "o.pay_status", payStatus);

        //售后状态
        wrapper.eq(CharSequenceUtil.isNotEmpty(afterSaleStatus), "oi.after_sale_status", afterSaleStatus);

        //投诉状态
        wrapper.eq(CharSequenceUtil.isNotEmpty(complainStatus), "oi.complain_status", complainStatus);

        //订单来源
        wrapper.like(CharSequenceUtil.isNotEmpty(clientType), "o.client_type", clientType);

        //按评价状态
        wrapper.eq(CharSequenceUtil.isNotEmpty(commentStatus), "oi.comment_status", commentStatus);

        //按评价状态
        wrapper.eq(isProxy != null, "o.is_proxy", isProxy);


        //按标签查询
        if (CharSequenceUtil.isNotEmpty(tag)) {
            String orderStatusColumn = "o.order_status";
            OrderTagEnum tagEnum = OrderTagEnum.valueOf(tag);
            switch (tagEnum) {
                //待付款
                case WAIT_PAY -> wrapper.eq(orderStatusColumn, OrderStatusEnum.UNPAID.name());

                //待发货
                case WAIT_SHIP -> wrapper.eq(orderStatusColumn, OrderStatusEnum.UNDELIVERED.name());

                //待收货
                case WAIT_ROG -> wrapper.in(orderStatusColumn, Arrays.asList(OrderStatusEnum.DELIVERED.name(),OrderStatusEnum.OVERVIEW.name()));

                //已取消
                case CANCELLED -> wrapper.eq(orderStatusColumn, OrderStatusEnum.CANCELLED.name());

                //已完成
                case COMPLETE -> wrapper.eq(orderStatusColumn, OrderStatusEnum.COMPLETED.name());

                case SUBJECT_TO_SALE -> wrapper.eq(orderStatusColumn, OrderStatusEnum.SUBJECT_TO_SALE.name());
                default -> {
                }
            }
        }

        // 依赖订单
        wrapper.eq(parentOrderSn != null, "o.parent_order_sn", parentOrderSn);
        // 促销活动id
        wrapper.eq(CharSequenceUtil.isNotEmpty(promotionId), "o.promotion_id", promotionId);

        wrapper.eq(CharSequenceUtil.isNotEmpty(orderPromotionType), "o.order_promotion_type", orderPromotionType);

        if (CharSequenceUtil.isNotEmpty(flowPrice)) {
            String[] s = flowPrice.split("_");
            if (s.length > 1) {
                wrapper.between("o.flow_price", s[0], s[1]);
            } else {
                wrapper.ge("o.flow_price", s[0]);
            }
        }
        wrapper.like(StringUtils.isNotEmpty(mhId), "o.mh_id", mhId);
        wrapper.like(StringUtils.isNotEmpty(mhName), "o.mh_name", mhName);
        if (mhOrder != null && mhOrder) {
            wrapper.and(q -> q.isNotNull("o.mh_id").and(q2 -> q2.ne("o.mh_id", "")));
        }
        wrapper.eq("o.delete_flag", false);

        //是否免税异常订单
        if (isErrorFree != null && isErrorFree) {
            wrapper.and(q -> q.isNotNull("o.customs_error_message").or().isNotNull("o.free_error_message"));
            wrapper.ne("o.order_status", OrderStatusEnum.CANCELLED.name());
        }
        //是否免税需要同步的订单
        if (syncOrder != null && syncOrder) {
            wrapper.eq("o.is_duty_free", true);
            wrapper.notIn("o.order_status", OrderStatusEnum.COMPLETED.name(), OrderStatusEnum.CANCELLED.name(), OrderStatusEnum.UNPAID.name());
        }

        return wrapper;
    }

}
